package server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.Set;

import com.apexsoft.monitor.common.MonitorConstant;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.util.FileCopyUtils;

import com.apexsoft.front.common.utils.SpringPropertyResourceReader;


public class JettyServer {

    private static final Logger log = LogManager.getRootLogger();
    private static String webXml;
    private static String propFile;
    private static String resouceBase = "src/main/webapp";
    private static String contextPath = "/monitor";
    private static Properties pp;
    private static String port = "8080";
    private static String maxThreads = "1000";
    private static String minThreads = "30";
    private static String idleTimeout = "60000";
    private static Server server = null;


    /**
     * jetty线程池状态
     */
    public static QueuedThreadPool getJettyThreadPool() {
        if (server != null) {
            return (QueuedThreadPool) server.getThreadPool();
        }
        return null;
    }

    public static Properties getConfigProperties() {
        if (pp == null) {
            log.error("配置文件加载失败");
            return new Properties();
        }
        return pp;
    }

    public static void main(String... args) throws Exception {
        ServerConnector connector = null;
        try {
            initArgs(args);
            // 初始化中心化配置
//			setConfig();
            //初始化Redis
//            initJedisPool();
            // 设置线程池
            QueuedThreadPool threadPool = new QueuedThreadPool();
            threadPool.setMaxThreads(Integer.valueOf(pp.getProperty("JETTY.THREAD.MAX", maxThreads)));
            threadPool.setMinThreads(Integer.valueOf(pp.getProperty("JETTY.THREAD.MIN", minThreads)));
            threadPool.setIdleTimeout(Integer.valueOf(pp.getProperty("JETTY.THREAD.TIMEOUT", idleTimeout)));

            // 创建上下文
            server = new Server(threadPool);

            // JMX
            // Setup JMX
            MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
            server.addEventListener(mbContainer);
            server.addBean(mbContainer);
            // Add loggers MBean to server (will be picked up by MBeanContainer
            // above)
            server.addBean(Log.getLog());

            WebAppContext context = new WebAppContext();

            // 开放端口
            connector = new ServerConnector(server);
            connector.setPort(Integer.valueOf(pp.getProperty("JETTY.PORT", port)));
            server.setConnectors(new Connector[]{connector});
            // 服务
            context.setContextPath(contextPath);
            context.setTempDirectory(new File("temp"));
            context.setDescriptor(webXml);
            context.setResourceBase(resouceBase);

            //修改jetty默认配置，允许运行时修改jsp、js文件内容
            String filePath = Thread.currentThread().getContextClassLoader().getResource("webdefault.xml").getPath();
            if (new File(filePath).exists()) {
                context.setDefaultsDescriptor(filePath);
            }
            //设置form表单的最大值，form表单过大时，可以提交
            //最大提交
            context.setMaxFormContentSize(5 * 1024 * 1024);

            Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
            classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");
            context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");
            server.setHandler(context);
            server.start();
            server.join();
        } catch (Exception e) {
            // TODO: handle exception
            log.error(e.getMessage(), e);
        } finally {
            if (connector != null) {
                connector.close();
            }
        }
    }

    private static void initArgs(String[] args) throws IOException {
        // 加载上下文
        if (args != null && args.length > 2) {
            resouceBase = args[2];
        }
        log.info("set resouceBase:" + resouceBase);
        // webXml文件加载
        if (args != null && args.length > 0 && new File(args[0]).exists()) {
            webXml = args[0];
        } else {
            try {

                webXml = Thread.currentThread().getContextClassLoader().getResource("jetty-web.xml").getPath();
                //构建web.mxl文件
                File webINF = new File(resouceBase + File.separator + "WEB-INF");
                if (!webINF.exists()) {
                    webINF.mkdirs();
                }
                File webxmlFile = new File(webINF, "web.xml");
                if (!webxmlFile.exists()) {
                    FileCopyUtils.copy(Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty-web.xml"), new FileOutputStream(webxmlFile));
                }
                webXml = webxmlFile.getAbsolutePath();
            } catch (NullPointerException e) {
                log.warn("jar中未发现jetty-web.xml", e);
            }
        }
        log.info("load webXml:" + webXml);
        // properties文件加载
        pp = new Properties();
        if (args != null && args.length > 1 && new File(args[1]).exists()) {
            propFile = args[1];
            pp.load(new FileInputStream(propFile));
        } else {
            try {
                propFile = Thread.currentThread().getContextClassLoader().getResource("config.properties").getPath();
            } catch (NullPointerException e) {
                log.warn("jar中未发现config.properties", e);
            }
            pp.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));
        }
        log.info("load propFile:" + propFile);
        Set<Object> keys = pp.keySet();
        for (Object key : keys) {
            log.info("prop:[" + key.toString() + ":" + pp.getProperty(key.toString()) + "]");
            SpringPropertyResourceReader.setProperty(key.toString(), pp.getProperty(key.toString()));
        }
        //加载上下文
        contextPath = pp.getProperty("JETTY.CONTEXTPATH", contextPath);
        log.info("load contextPath:" + contextPath);
    }

//	private static void setConfig() throws Exception {
//		String driverClass = pp.getProperty("DB.MYSQL.DriverClass");
//		String jdbcUrl = pp.getProperty("DB.MYSQL.JdbcUrl");
//		String user = pp.getProperty("DB.MYSQL.User");
//		String password = pp.getProperty("DB.MYSQL.Password");
//
//		Connection con = null;
//		Statement st = null;
//		ResultSet rs = null;
//		try {
//			Class.forName(driverClass);
//			con = DriverManager.getConnection(jdbcUrl, user, password);
//			st = con.createStatement();
//			rs = st.executeQuery("select * from t_config");
//
//			while (rs.next()) {
//				String key = rs.getString("key");
//				String value = rs.getString("value");
//
//                if(key.startsWith("redis.")){       //增加redis的配置   监控的时候需要发布到esb的redis
//                    String saveKey = "esb."+key;
//                    log.info("配置参数[" + saveKey + ":" + value + "]");
//                    System.setProperty(saveKey, value);
//                    pp.setProperty(saveKey, value);
//                    SpringPropertyResourceReader.setProperty(saveKey, value);
//                    continue;
//                }
//                System.setProperty(key, value);
//                pp.setProperty(key, value);
//                SpringPropertyResourceReader.setProperty(key, value);
//
//			}
//		}finally {
//			if (rs != null) {
//				try {
//					rs.close();
//				} catch (SQLException e) {
//					log.warn(e.getMessage(), e);
//				}
//			}
//			if (st != null)
//				try {
//					st.close();
//				} catch (SQLException e) {
//					log.warn(e.getMessage(), e);
//				}
//			if (con != null)
//				try {
//					con.close();
//				} catch (SQLException e) {
//					log.warn(e.getMessage(), e);
//				}
//		}
//	}

//    private static void initJedisPool() {
//        try {
//            //redis连接池
//            JedisPoolConfig config = new JedisPoolConfig();
//            config.setMaxTotal(100);
//            config.setMaxIdle(20);
//            config.setMaxWaitMillis(1000l);
//            RedisImpl.initJedisPool(
//                    new JedisPool(
//                            config,
//                            pp.getProperty("esb.redis.host"),
//                            Integer.parseInt(pp.getProperty("esb.redis.port")),
//                            5000,
//                            pp.getProperty("esb.redis.password")
//                    )
//            );
//            log.info("load redis ConnLoader success");
//        } catch (Exception e) {
//            log.error(e.getMessage());
//            e.printStackTrace();
//        }
//    }
}
